package aip.ui.consultation.srvc;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;

import aip.core.dao.consultation.ConsultationDao;
import aip.core.dao.information.CatalogDao;
import aip.core.dao.todo.TodoDao;
import aip.core.dao.user.UserDao;
import aip.core.model.consultation.Consultation;
import aip.core.model.information.Catalog;
import aip.core.model.todo.Todo;
import aip.core.mvc.pageController.PageController;
import aip.ui.consultation.web.spring.ConsultationEditForm;
import aip.ui.consultation.web.spring.ConsultationListForm;
import aip.ui.user.util.UserHelper;

import com.googlecode.horncomb.bean.filter.SimpleMapConditionSet;
import com.googlecode.horncomb.bean.paged.PagedList;
import com.googlecode.horncomb.bean.paged.PagedSetting;
import com.googlecode.horncomb.web.util.TagUtils;

/**
 * Consultation form service
 * <p>
 * 负责人/principal:<br/>
 * 修改记录/revision:<br/>
 * 日期:<br/>
 * 修改人:<br/>
 * 修改说明:<br/>
 * @author
 * @version $Id$
 */
public class ConsultationFormService
{
    private ConsultationDao consultationDao;
    private CatalogDao catalogDao;
    private TodoDao todoDao;
    private UserDao userDao;

    /**
     * Consultation列表
     * @param form
     *        表单对象
     * @return 列表页面数据
     * @throws Exception
     */
    public Map<String, Object> listReference(ConsultationListForm form)
            throws Exception
    {
        Map<String, Object> ref = new HashMap<String, Object>();
        PagedSetting ps = form.getPagedSettingMap().values().iterator().next();
        // 查询条件仅含一级栏目时，查询一级栏目下所有二级栏目
        if (ps.getConditionSet() != null)
        {
            Map<String, Object> consMap = ps.getConditionSet()
                    .getConstraintsMap();
            if (consMap.containsKey("catalog"))
            {
                Integer catId = Integer.valueOf(consMap.get("catalog")
                        .toString());
                Catalog cat = catalogDao.getAllCatalog().get(catId);
                if (cat.getLevel() == 1)
                {
                    consMap.put("catalogs", cat.getChildren().keySet().toArray(
                            new Integer[] {}));
                }
            }
        }
        // 如果是专家，则只查看属于自己的咨询单
        if (UserHelper.getUser().getType().equals("expert"))
        {
            if (ps.getConditionSet() == null)
            {
                ps.setConditionSet(new SimpleMapConditionSet());
            }
            ps.getConditionSet().getConstraintsMap().put("expert",
                    UserHelper.getUser().getUsername());
        }

        PagedList<List<? extends Consultation>> result = this.consultationDao
                .query(ps.getConditionSet(), ps.getOrder(), ps.getPage(), ps
                        .getPageSize());
        ref.put("consultationList", result.getSource()); //$NON-NLS-1$
        ref.put("totalRows", result.getNrOfElements()); //$NON-NLS-1$
        ref.put("userMap", TagUtils.convertToMap(this.userDao
                .queryListByIds(TagUtils.parseIdString(result.getSource(),
                        "enterprise", "customService", "expert").toArray(
                        new String[] {})), "username"));
        ref.put("allCatalog", catalogDao.getAllCatalog());
        ref.put("catalogMap", catalogDao.getCatalogMap());
        ref.put("stateMap", Consultation.stateMap);
        return ref;
    }

    /**
     * 删除选中的项
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void deleteItems(ConsultationListForm form) throws Exception
    {
        if (form.getSelectedIds().size() > 0)
        {
            this.consultationDao.deleteByIds(form.getSelectedIds());
        }
    }

    /**
     * 派发选中的项
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void saveAssignByItems(ConsultationListForm form) throws Exception
    {
        if (form.getSelectedIds().size() > 0)
        {
            this.consultationDao.saveAssignByItems(form.getSelectedIds(), form
                    .getExpert());
            this.todoDao.update(form.getSelectedIds(), new Todo(form
                    .getExpert(), "回复咨询单", Todo.STATE_CONS_TOREPLY));
        }
    }

    /**
     * 获得Consultation表单主对象
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void get(ConsultationEditForm form) throws Exception
    {
        if (form != null && form.getId() > 0)
        {
            Consultation consultation = this.consultationDao.getById(form
                    .getId());
            BeanUtils.copyProperties(consultation, form);
        }
    }

    /**
     * 显示编辑Consultation界面相关数据
     * @param form
     *        表单对象
     * @return 显示页面数据
     * @throws Exception
     */
    public Map<String, Object> showReference(ConsultationEditForm form)
            throws Exception
    {
        // other reference data
        Map<String, Object> ref = new HashMap<String, Object>();
        ref.put("stateMap", Consultation.stateMap);
        ref.put("allCatalog", catalogDao.getAllCatalog());
        ref.put("catalogMap", catalogDao.getCatalogMap());

        if (form.getId() != 0)
        {
            List<? extends Todo> todos = this.todoDao.queryByDomain(form
                    .getId());
            ref.put("todoList", todos);
            ref.put("userMap", TagUtils.convertToMap(this.userDao
                    .queryListByIds(TagUtils.parseIdString(todos, "actor")
                            .toArray(new String[] {})), "username"));
        }
        return ref;
    }

    /**
     * 保存Consultation表单
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void save(ConsultationEditForm form) throws Exception
    {
        boolean isNew = form.getId() == 0;
        this.consultationDao.save(form);

        if (isNew)
        {
            Todo submit = new Todo(UserHelper.getUser().getUsername(), "提交咨询单",
                    Todo.STATE_CONS_DONE);
            submit.setCreate(form.getSubmitTime());
            submit.setDone(form.getSubmitTime());
            submit.setDomain(form.getId());
            this.todoDao.save(submit);

            Todo assign = new Todo(null, "分配咨询单", Todo.STATE_CONS_TOASSIGN);
            assign.setCreate(form.getSubmitTime());
            assign.setDomain(form.getId());
            this.todoDao.save(assign);
        }
        else if (form.getState().equals(Consultation.STATE_ASIGNED))
        {
            // 咨询单已分配，未回复
            this.todoDao.update(form.getId(), new Todo(form.getExpert(),
                    "回复咨询单", Todo.STATE_CONS_TOREPLY));
        }
        else if (form.getState().equals(Consultation.STATE_REPLIED))
        {
            // 咨询单已回复
            this.todoDao.update(form.getId(), null);
        }
    }

    /**
     * 删除单个Consultation
     * @param form
     *        表单对象
     * @throws Exception
     */
    public void deleteItem(ConsultationEditForm form) throws Exception
    {
        this.consultationDao.deleteById(form.getId());
    }

    /**
     * 首页展现Consultation列表
     * @param form
     *        表单对象
     * @return 列表页面数据
     * @throws Exception
     */
    public Map<String, Object> consEntpList(ConsultationListForm form)
            throws Exception
    {
        Map<String, Object> ref = new HashMap<String, Object>();
        PagedSetting ps = form.getPagedSettingMap().values().iterator().next();
        // 查询条件仅含一级栏目时，查询一级栏目下所有二级栏目
        if (ps.getConditionSet() != null)
        {
            Map<String, Object> consMap = ps.getConditionSet()
                    .getConstraintsMap();
            if (consMap.containsKey("catalog"))
            {
                Integer catId = Integer.valueOf(consMap.get("catalog")
                        .toString());
                Catalog cat = catalogDao.getAllCatalog().get(catId);
                if (cat.getLevel() == 1)
                {
                    consMap.put("catalogs", cat.getChildren().keySet().toArray(
                            new Integer[] {}));
                }
            }
        }
        // 如果只查看属于自己的咨询单
        if (UserHelper.getUser().getType().equals("company"))
        {
            if (ps.getConditionSet() == null)
            {
                ps.setConditionSet(new SimpleMapConditionSet());
            }
            ps.getConditionSet().getConstraintsMap().put("enterprise",
                    UserHelper.getUser().getUsername());
        }

        PagedList<List<? extends Consultation>> result = this.consultationDao
                .query(ps.getConditionSet(), ps.getOrder(),
                        form.getStart() + 1, 20);
        ref.put("consultationList", result.getSource()); //$NON-NLS-1$
        ref.put("totalRows", result.getNrOfElements()); //$NON-NLS-1$
        String url = "../consultation/consEntpList.shtml?ec_f_state="
                .concat(String.valueOf(ps.getConditionSet().getConstraintsMap()
                        .get("state")));
        // 分页
        if (result.getSource().size() > 0)
        {
            PageController pc = new PageController();
            pc.setPageSize(20);
            pc.setRowCount(result.getNrOfElements());
            pc.setShowPage(form.getStart());
            pc.setUrl(url);
            pc.setShowPageEnum(new Boolean(true));
            pc.setDivClassName("page");
            pc.setShowInput(new Boolean(true));
            pc.setShowPageEnumCount(5);
            pc.setButtonClassName("pageGoButton");
            pc.setInputClassName("pageInput");
            ref.put("pageStr", pc.getPageController());
        }

        ref.put("userMap", TagUtils.convertToMap(this.userDao
                .queryListByIds(TagUtils.parseIdString(result.getSource(),
                        "enterprise", "customService", "expert").toArray(
                        new String[] {})), "username"));
        ref.put("allCatalog", catalogDao.getAllCatalog());
        ref.put("catalogMap", catalogDao.getCatalogMap());
        ref.put("stateMap", Consultation.stateMap);
        return ref;
    }

    /**
     * @param consultationDao
     *        the consultationDao to set
     */
    public void setConsultationDao(ConsultationDao consultationDao)
    {
        this.consultationDao = consultationDao;
    }

    /**
     * @param catalogDao
     *        the catalogDao to set
     */
    public void setCatalogDao(CatalogDao catalogDao)
    {
        this.catalogDao = catalogDao;
    }

    /**
     * @param todoDao
     *        the todoDao to set
     */
    public void setTodoDao(TodoDao todoDao)
    {
        this.todoDao = todoDao;
    }

    /**
     * @param userDao
     *        the userDao to set
     */
    public void setUserDao(UserDao userDao)
    {
        this.userDao = userDao;
    }
}
